package com.glink.manage.service.Impl;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.glink.common.contants.BaseCodeConstants;
import com.glink.common.exception.GeneralSimpleException;
import com.glink.common.util.BaseCommonUtils;
import com.glink.manage.common.Constants;
import com.glink.manage.common.PoiTools;
import com.glink.manage.domain.ParticipatingUnitBean;
import com.glink.manage.dto.participatingunit.*;
import com.glink.manage.mapper.ParticipatingUnitMapper;
import com.glink.manage.service.ConstructionWorkUnitRelaService;
import com.glink.manage.service.ParticipatingUnitService;
import com.glink.manage.service.PersonManageService;
import com.glink.manage.vo.org.OrgInfoVO;
import com.glink.manage.vo.participatingunit.ParticipatingUnitBaseVO;
import com.glink.manage.vo.participatingunit.ParticipatingUnitListVO;
import com.glink.manage.vo.participatingunit.ParticipatingUnitPageVO;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Row;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author  qiushaoshan
 * @since 2025-01-08
 */
@Slf4j
@Service
public class ParticipatingUnitServiceImpl extends ServiceImpl<ParticipatingUnitMapper, ParticipatingUnitBean> implements ParticipatingUnitService {

    @Autowired
    @Lazy
    private ConstructionWorkUnitRelaService constructionWorkUnitRelaService;

    @Autowired
    @Lazy
    private PersonManageService personManageService;
    
    /**
     * 保存参建单位
     *
     * @param dto 保存信息
     * @return 保存状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean saveParticipatingUnit(ParticipatingUnitSaveDTO dto) {
        ParticipatingUnitBean participatingUnitBean = new ParticipatingUnitBean();
        BeanUtils.copyProperties(dto, participatingUnitBean);
        participatingUnitBean.setIfDelete(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02);
        participatingUnitBean.setObjId(BaseCommonUtils.generateUUID());

        return this.save(participatingUnitBean);
    }

    /**
     * 更新参建单位
     *
     * @param dto 更新信息
     * @return 保存状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public boolean updateParticipatingUnit(ParticipatingUnitUpdateDTO dto) throws GeneralSimpleException {
        ParticipatingUnitBean participatingUnitBean = this.getById(dto.getObjId());
        if (Objects.isNull(participatingUnitBean)) {
            throw new GeneralSimpleException("500001", dto.getObjId());
        }

        BeanUtils.copyProperties(dto, participatingUnitBean);

        return this.updateById(participatingUnitBean);
    }

    /**
     * 根据参建单位ID查询参建单位详情
     *
     * @param dto 参建单位ID
     * @return 参建单位详情
     */
    @Override
    public ParticipatingUnitBaseVO findById(ParticipatingUnitIdDTO dto) throws GeneralSimpleException {
        ParticipatingUnitBean participatingUnitBean = this.baseMapper.getByIdAndNotDel(dto.getObjId());
        if (Objects.isNull(participatingUnitBean)) {
            throw new GeneralSimpleException("500001", dto.getObjId());
        }
        ParticipatingUnitBaseVO baseVO = new ParticipatingUnitBaseVO();

        BeanUtils.copyProperties(participatingUnitBean, baseVO);
        return baseVO;
    }

    /**
     * 分页查询
     *
     * @param dto 查询条件
     * @return 分页信息
     */
    @Override
    public IPage<ParticipatingUnitPageVO> findByPage(ParticipatingUnitPageDTO dto) {
        IPage<ParticipatingUnitBean> participatingUnitBeanIPage = new Page<>(dto.getPage(), dto.getSize());

        IPage<ParticipatingUnitBean> unitBeanIPage = this.lambdaQuery()
                .like(StringUtils.isNotEmpty(dto.getUnitName()), ParticipatingUnitBean::getUnitName, dto.getUnitName())
                .eq(StringUtils.isNotEmpty(dto.getIfBlacklist()) && StringUtils.equals(dto.getIfBlacklist(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01), ParticipatingUnitBean::getIfBlacklist, dto.getIfBlacklist())
                .and(StringUtils.isNotEmpty(dto.getIfBlacklist()) && !StringUtils.equals(dto.getIfBlacklist(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01), w -> w.ne(ParticipatingUnitBean::getIfBlacklist, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01)
                        .or()
                        .isNull(ParticipatingUnitBean::getIfBlacklist))
                .eq(ParticipatingUnitBean::getIfDelete, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)
                .orderByAsc(ParticipatingUnitBean::getCreateTime)
                .orderByAsc(ParticipatingUnitBean::getObjId)
                .page(participatingUnitBeanIPage);

        IPage<ParticipatingUnitPageVO> pageVOIPage = new Page<>(unitBeanIPage.getCurrent(), unitBeanIPage.getSize(), unitBeanIPage.getTotal());
        List<ParticipatingUnitPageVO> pageVOList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(unitBeanIPage.getRecords())) {
            unitBeanIPage.getRecords().forEach(measurePointBean -> {
                ParticipatingUnitPageVO unitPageVO = new ParticipatingUnitPageVO();
                BeanUtils.copyProperties(measurePointBean, unitPageVO);
                pageVOList.add(unitPageVO);
            });
            pageVOIPage.setRecords(pageVOList);
        }
        return pageVOIPage;
    }

    /**
     * 导入参建单位
     *
     * @param multipartFile 导入文件
     * @return 数量
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Integer importParticipatingUnit(MultipartFile multipartFile) throws GeneralSimpleException {
        List<ParticipatingUnitBean> saveList = Lists.newArrayList();

        String filePath = uploadXls(multipartFile);
        //获取所有行
        Iterator<Row> rows = PoiTools.getFirstSheetRowsFromFilePath(filePath);
        if (Objects.isNull(rows)) {
            return 0;
        }
        StringBuilder errorMessage = new StringBuilder();
        int count = 0;
        int saveSuccessCount = 0;

        List<String> unitNameList = this.baseMapper.findAllUnitName();
        if(unitNameList == null){
            unitNameList = Lists.newArrayList();
        }
        while (rows.hasNext()) {
            Row thisRow = rows.next();
            int colIndex = 0;
            count++;
            if (count <= 1) {
                continue;
            }
            try {
                if (PoiTools.isLastRow(thisRow)) {
                    break;
                }

                ParticipatingUnitBean save = new ParticipatingUnitBean();
                String standardDeviceId = BaseCommonUtils.generateUUID();
               
                String unitName = PoiTools.getCellStringValue(thisRow.getCell(colIndex++));
                if(StringUtils.isBlank(unitName)){
                    continue;
                }
                if(unitNameList.contains(unitName)){
                    save = this.lambdaQuery()
                            .eq(ParticipatingUnitBean::getUnitName, unitName)
                            .eq(ParticipatingUnitBean::getIfDelete, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)
                            .last(Constants.LAST_SQL).one();
                    if(Objects.isNull(save)){
                        List<ParticipatingUnitBean> unitBeanList = saveList.stream().filter(obj -> StringUtils.equals(obj.getUnitName(), unitName)).collect(Collectors.toList());
                        if(CollectionUtils.isNotEmpty(unitBeanList)){
                            save = unitBeanList.get(0);
                        }else{
                            save = new ParticipatingUnitBean();
                            save.setObjId(standardDeviceId);
                        }
                    }
                }else{
                    save.setObjId(standardDeviceId);
                }
                unitNameList.add(unitName);
                
                // 单位名称
                save.setUnitName(unitName);
                //单位简称
                save.setUnitAbbreviation(PoiTools.getCellStringValue(thisRow.getCell(colIndex ++)));
                // 法人
                save.setLegalPerson(PoiTools.getCellStringValue(thisRow.getCell(colIndex ++)));
                // 联系人
                save.setContacts(PoiTools.getCellStringValue(thisRow.getCell(colIndex ++)));
                // 联系电话
                save.setContactNumber(PoiTools.getCellStringValue(thisRow.getCell(colIndex ++)));
                // 经营范围
                save.setBusinessScope(PoiTools.getCellStringValue(thisRow.getCell(colIndex ++)));
//                // 营业执照
//                save.setBusinessLicense(PoiTools.getCellStringValue(thisRow.getCell(colIndex)));
                // 是否黑名单
                save.setIfBlacklist(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02);

                saveSuccessCount++;
                saveList.add(save);

            } catch (Exception e) {
                e.printStackTrace();
                log.info("解析异常:{}", e.getMessage());
                errorMessage.append("行数:").append(count).append("列数:").append(colIndex + 1).append("解析出错:").append(e.getMessage()).append("|");
            }
        }
        
        try {
            this.saveOrUpdateBatch(saveList);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("数据保存失败!{}", e.getMessage());
        } finally {
            File deleteFile = new File(filePath);
            deleteFile.delete();
        }
        if (StringUtils.isNotBlank(errorMessage.toString())) {
            throw new GeneralSimpleException("600053", errorMessage.toString(), String.valueOf(saveSuccessCount));
        }
        return saveSuccessCount;
    }

    private String uploadXls(MultipartFile file) {
        String orgName = file.getOriginalFilename();
        String oldExt = StringUtils.substring(orgName, Objects.requireNonNull(orgName).lastIndexOf("."));
        String xlsDir = new File(System.getProperty("user.dir")) + "/xls/";
        String filePath = xlsDir + BaseCommonUtils.generateUUID() + oldExt;
        log.info("准备生成文件  {}", filePath);
        try {
            File xlsFile = new File(filePath);
            if (!xlsFile.getParentFile().exists()) {
                xlsFile.getParentFile().mkdirs();
            }
            file.transferTo(new File(filePath));
            return filePath;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 查询参建单位
     *
     * @return 参建单位列表
     */
    @Override
    public List<ParticipatingUnitListVO> findList() {
        return findListByObjIdIn(null, false);
    }

    /**
     * 参建单位加入黑名单
     *
     * @param dto 参建单位ID
     * @return 加入黑名单状态
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean addBlacklist(ParticipatingUnitBlackListIdDTO dto) throws GeneralSimpleException {
        ParticipatingUnitBean participatingUnitBean = this.baseMapper.getByIdAndNotDel(dto.getObjId());
        if (Objects.nonNull(participatingUnitBean)) {
            participatingUnitBean.setIfBlacklist(dto.getIfBlacklist());
            boolean status = updateById(participatingUnitBean);
            if(StringUtils.equals(dto.getIfBlacklist(), BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01) && status){
                // 加入黑名单则解绑所有的工程
                status = constructionWorkUnitRelaService.delUnit(participatingUnitBean.getObjId());
            }
            return status;
        } else {
            throw new GeneralSimpleException("500001", dto.getObjId());
        }
    }

    /**
     * 根据参建单位ID查询参建单位名称
     *
     * @param participatingUnitObjId 参建单位ID
     * @return 参建单位名称
     */
    @Override
    public String findNameByObjId(String participatingUnitObjId) {
        ParticipatingUnitBean participatingUnitBean = this.baseMapper.getByIdAndNotDel(participatingUnitObjId);
        if (Objects.nonNull(participatingUnitBean)) {
            return participatingUnitBean.getUnitName();
        }
        return null;
    }

    /**
     * 根据ID查询参建单位信息
     *
     * @param unitIdList 参建单位ID
     * @return 参建单位信息
     */
    @Override
    public List<ParticipatingUnitListVO> findListByObjIdIn(List<String> unitIdList, boolean ifQueryBlacklist) {
        List<ParticipatingUnitBean> participatingUnitBeanList = this.lambdaQuery()
                .and(w -> w.eq(ParticipatingUnitBean::getIfBlacklist, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)
                        .or()
                        .isNull(ParticipatingUnitBean::getIfBlacklist))
                .eq(ParticipatingUnitBean::getIfDelete, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)
                .and(!ifQueryBlacklist, w -> w.eq(ParticipatingUnitBean::getIfBlacklist, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)
                        .or()
                        .isNull(ParticipatingUnitBean::getIfBlacklist))
                .in(CollectionUtils.isNotEmpty(unitIdList), ParticipatingUnitBean::getObjId, unitIdList)
                .orderByAsc(ParticipatingUnitBean::getCreateTime)
                .orderByAsc(ParticipatingUnitBean::getObjId)
                .list();
        List<ParticipatingUnitListVO> unitListVOList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(participatingUnitBeanList)) {
            participatingUnitBeanList.forEach(participatingUnitBean -> {
                ParticipatingUnitListVO unitListVO = new ParticipatingUnitListVO();
                unitListVO.setObjId(participatingUnitBean.getObjId());
                unitListVO.setUnitName(participatingUnitBean.getUnitName());
                unitListVOList.add(unitListVO);
            });
        }
        return unitListVOList;
    }
    
    @Override
    public OrgInfoVO findParticipatingUnitTree() {
        OrgInfoVO orgInfoVO = null;
        // 查询参建单位
        List<ParticipatingUnitBean> participatingUnitBeanList = this.lambdaQuery()
                .eq(ParticipatingUnitBean::getIfDelete, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)
                .orderByAsc(ParticipatingUnitBean::getUnitName)
                .orderByAsc(ParticipatingUnitBean::getObjId)
                .list();
        if (CollectionUtils.isNotEmpty(participatingUnitBeanList)){
            orgInfoVO = new OrgInfoVO();
            orgInfoVO.setOrgId(Constants.PARTICIPATION_UNIT_ORG_ID);
            orgInfoVO.setName("参建单位");
            orgInfoVO.setIfParticipatingUnit(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01);
            orgInfoVO.setIfEngDepartment(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02);

            List<OrgInfoVO> orgInfoVOList = Lists.newArrayList();
            participatingUnitBeanList.forEach(participatingUnitBean -> {
                OrgInfoVO children = new OrgInfoVO();
                children.setOrgId(participatingUnitBean.getObjId());
                children.setName(participatingUnitBean.getUnitName());
                children.setIfParticipatingUnit(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01);
                children.setIfEngDepartment(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02);
                orgInfoVOList.add(children);
            });
            orgInfoVO.setChildrenList(orgInfoVOList);
        }
        return orgInfoVO;
    }

    /**
     * 根据单位信息查询参建单位对象
     *
     * @param orgIdList 单位ID
     * @return 单位信息
     */
    @Override
    public OrgInfoVO findParticipatingUnitTreeByIdIn(List<String> orgIdList) {
        OrgInfoVO orgInfoVO = null;
        // 查询参建单位
        List<ParticipatingUnitBean> participatingUnitBeanList = this.lambdaQuery()
                .in(ParticipatingUnitBean::getObjId, orgIdList)
                .orderByAsc(ParticipatingUnitBean::getUnitName)
                .orderByAsc(ParticipatingUnitBean::getObjId)
                .list();
        if (CollectionUtils.isNotEmpty(participatingUnitBeanList)){
            orgInfoVO = new OrgInfoVO();
            orgInfoVO.setOrgId(Constants.PARTICIPATION_UNIT_ORG_ID);
            orgInfoVO.setName("参建单位");
            orgInfoVO.setIfParticipatingUnit(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01);
            orgInfoVO.setIfEngDepartment(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02);

            List<OrgInfoVO> orgInfoVOList = Lists.newArrayList();
            participatingUnitBeanList.forEach(participatingUnitBean -> {
                OrgInfoVO children = new OrgInfoVO();
                children.setOrgId(participatingUnitBean.getObjId());
                children.setName(participatingUnitBean.getUnitName());
                children.setIfParticipatingUnit(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode01);
                children.setIfEngDepartment(BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02);
                orgInfoVOList.add(children);
            });
            orgInfoVO.setChildrenList(orgInfoVOList);
        }
        return orgInfoVO;
    }

    /**
     * 根据ID删除参建单位信息
     * 参建单位删除，参建单位对用用户的账号锁定
     * @param dto ID
     * @return 参建单位
     */
    @Override
    @Transactional(value = "transactionManager", propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public Boolean delById(ParticipatingUnitIdDTO dto) {
        ParticipatingUnitBean participatingUnitBean = this.lambdaQuery().eq(ParticipatingUnitBean::getObjId, dto.getObjId()).one();
        if(Objects.nonNull(participatingUnitBean)){
            boolean status = removeById(dto.getObjId());
            if(status){
                constructionWorkUnitRelaService.delUnitByUnitId(dto.getObjId());
                
                // 参建单位人员账号锁定
                personManageService.lockPersonAccountByOrgId(participatingUnitBean.getObjId());
            }
            return status;
        }
        return false;
    }

    /**
     * 查询所有参建单位ID
     *
     * @return 参建单位ID
     */
    @Override
    public List<String> getAllId() {
        // 查询参建单位
        List<ParticipatingUnitBean> participatingUnitBeanList = this.lambdaQuery()
                .eq(ParticipatingUnitBean::getIfDelete, BaseCodeConstants.CodeType_WhetherCode.KEY_WhetherCode02)
                .orderByAsc(ParticipatingUnitBean::getUnitName)
                .orderByAsc(ParticipatingUnitBean::getObjId)
                .list();
        if(CollectionUtils.isNotEmpty(participatingUnitBeanList)){
            return participatingUnitBeanList.stream().map(ParticipatingUnitBean::getObjId).collect(Collectors.toList());
        }
        return null;
    }
}
